package ru.spb.nicetu.schoolproject.gui;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import ru.spb.nicetu.schoolproject.data.ComboBoxData;
import ru.spb.nicetu.schoolproject.data.HibernateUtil;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * Шаблон для создания карточек.
 * @param <T> тип объекта, для которого создается карточка
 * @param <TT> тип объекта для JComboBox
 * @author dchernyshov on 11.04.15.
 */
public abstract class CardTemplate<T, TT> extends JDialog {
    protected JLabel firstHorizontalBoxLabelName;
    protected JTextField lessonNumField;

    protected JComboBox comboBox;
    protected JButton okButton;
    protected JButton cancelButton;

    private TT[] comboArray;
    private ComboBoxData<TT> comboBoxData;

    private Session session;

    public boolean modifyCard;

    public T object;

    public abstract boolean checkCard();
    public abstract void inputValue(T object);

    public CardTemplate() {}

    public CardTemplate(Class<TT> clazz, String cardTitle, boolean modifyCard, T object) {
        this.modifyCard = modifyCard;
        this.object = object;
        setFrameSize();
        setTitle(cardTitle);
        setModalityType(ModalityType.APPLICATION_MODAL);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        comboBoxData = new ComboBoxData(clazz);
        comboArray = comboBoxData.getComboArray();

    }

    public void okButton() {
        if (checkCard()) {
            if (!modifyCard) {
                inputValue(object);
                addDataToDB(object);
            }
            else {
                inputValue(object);
                updateObject(object);
            }
        }
    }

    public Box createHorizontalBox(String labelName, Class clazz, JComboBox jComboBox) {
        Box box = Box.createHorizontalBox();
        JLabel label = new JLabel(labelName);
        box.add(label);
        box.add(Box.createHorizontalStrut(10));
        box.add(jComboBox);
        box.add(Box.createHorizontalGlue());
        return box;
    }

    public Box createFirstHorizontalBox(String labelName) {
        Box box = Box.createHorizontalBox();
        firstHorizontalBoxLabelName = new JLabel(labelName);
        box.add(firstHorizontalBoxLabelName);
        box.add(Box.createHorizontalStrut(10));
        lessonNumField = new JTextField(20);
        lessonNumField.setMaximumSize(
                lessonNumField.getPreferredSize());
        box.add(lessonNumField);
        box.add(Box.createHorizontalGlue());
        return box;
    }

    public Box createSecondHorizontalBox(String labelName) {
        Box box = Box.createHorizontalBox();
        JLabel disciplineLabel = new JLabel(labelName);
        box.add(disciplineLabel);
        box.add(Box.createHorizontalStrut(10));
        comboBox = new JComboBox(comboArray);
        comboBox.setMaximumSize(comboBox.getPreferredSize());
        box.add(comboBox);
        box.add(Box.createHorizontalGlue());
        return box;
    }

    public Box createLastHorizontalBox() {
        Box box = Box.createHorizontalBox();
        okButton = new JButton("Ok");
        okButton.addActionListener(new BtnOkListener());
        box.add(okButton);
        box.add(Box.createHorizontalStrut(10));
        cancelButton = new JButton("Отмена");
        cancelButton.addActionListener(new BtnCancelListener());
        box.add(cancelButton);
        return box;
    }

    public void setFrameSize() {
        Toolkit kit = Toolkit.getDefaultToolkit();
        Dimension screenSize = kit.getScreenSize();
        int screenHeight = screenSize.height;
        int screenWidth = screenSize.width;
        setSize(screenWidth / 6, screenHeight / 6);
        setLocationByPlatform(true);
    }

    public void addDataToDB(T data) {
        session = HibernateUtil.getInstance().getSession();
        try {
            session.beginTransaction();
            session.save(data);
            session.getTransaction().commit();
        }
        catch (HibernateException e) {
            JOptionPane.showMessageDialog(null,
                    "Ошибка добовления. Возможно, элемент с такими параметрами уже существует.");
            session.getTransaction().rollback();
        }
        finally {
            HibernateUtil.closeSession();
        }
    }

    public class BtnOkListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent actionEvent) {
            okButton();
        }
    }

    public class BtnCancelListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent actionEvent) {
            dispose();
        }
    }

    public void errorDialog(String error) {
        JOptionPane.showMessageDialog(null, error, "Ошибка ввода",JOptionPane.ERROR_MESSAGE);
    }

    public void updateObject(T object) {
        session = HibernateUtil.getInstance().getSession();
        try {
            session.beginTransaction();
            session.merge(object);
            session.getTransaction().commit();
        }
        catch (HibernateException e) {
            JOptionPane.showMessageDialog(null,
                    "Ошибка редактирования");
            session.getTransaction().rollback();
        }
        finally {
            HibernateUtil.closeSession();
        }
    }
}
